﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ProjectFitus.Models;
using System.Configuration;

namespace ProjectFitus.Controllers
{
	public class JsonUser : IEquatable<JsonUser>
	{
		public long id { get; set; }
		public string firstName { get; set; }
		public string lastName { get; set; }

		public override int GetHashCode()
		{
			return Convert.ToInt32( id );
		}

		public override bool Equals(object obj)
		{
			return this.id == ((JsonUser)obj).id;
		}

		public bool Equals(JsonUser other)
		{
			return this.id == other.id;
		}
	}

	[HandleError]
	public class ArticleController : Controller
    {
		protected override void OnException(ExceptionContext fc)
		{
			base.OnException(fc);
			FitusLogger.Instance.LogException(fc.Exception);
		}

		IDBFitusRepository m_repo;

        public ArticleController()
        {
            m_repo = new DBFitusRepository();
			System.Web.HttpRuntime.Cache["MenuItemsSub"] = m_repo.GetMenuItemsByParentId(3); //uppfæri submenu fyrir greinar
        }
        
        // Testing smiður.
        public ArticleController (IDBFitusRepository repo)
        {
            m_repo = repo;
        }

        public ActionResult Index(int? id)
        {
			System.Web.HttpRuntime.Cache["MenuItemsSub"] = m_repo.GetMenuItemsByParentId(3);
			int intParentId = (id.HasValue) ? id.Value : 1;
			var article = m_repo.GetAllArticles();
			IEnumerable<TextContentCategory> tccCol = m_repo.GetTextContentCategoriesByParentId(intParentId, 1);
			ArticleAndCategoriesModel model = new ArticleAndCategoriesModel {  artModel = article, catsModel=tccCol };

			return View(model);
        }

		public ActionResult Details(long? id)
		{
			if (!id.HasValue)
				return View("Index");
			var article = m_repo.GetArticleById(id.Value);
			User articleAuthor = m_repo.GetUserById(article.submittedByUserId);
			ViewData["Author"] = String.Format("{0} {1}", articleAuthor.firstName, articleAuthor.lastName);
			IEnumerable<SelectListItem> catList = m_repo.GetContentCategoryByParentId(1, 1);
			string catListString = "";
			foreach (var cl in catList)
				catListString = cl.Text + ", ";
			ViewData["CatsString"] = catListString.Substring(0, catListString.Length - 2);
			ViewData["AuthorList"] = m_repo.GetUserAuthorsByArticleId(article.id);
			if (article.ArticleToCategories.Count > 0)
				ViewData["SelectedCategoryName"] = m_repo.GetCategoryNameById(article.ArticleToCategories.FirstOrDefault().categoryId).categoryTitle;
			else
				ViewData["SelectedCategoryName"] = "flokkur er óskráður";
			//tilraun útaf html encode í views.
			return View(article);
		}

        //
        // GET: /Article/Create

        [Authorize(Roles= "Administrators")]
        public ActionResult Create()
        {
			ViewData["AuthorList"] = m_repo.GetAllUsersAsSelList();
			ViewData["Cats"] = m_repo.GetContentCategoryByParentId(1, 1);
            return View();
        } 

        //
        // POST: /Article/Create

		[HttpPost]
		[Authorize(Roles = "Administrators")]
		public ActionResult Create(FormCollection formData)
		{
			//if (ModelState.IsValid)
			//{
			ArticleContent article = new ArticleContent();
			if (!String.IsNullOrEmpty(formData["title"]) && !String.IsNullOrEmpty(formData["contentText"])
				&& !String.IsNullOrEmpty(formData["introText"]) && !String.IsNullOrEmpty(formData["Cats"]))
			{
				System.Web.Security.MembershipUser CurrentUser = System.Web.Security.Membership.GetUser(User.Identity.Name);
				article.submittedByUserId = m_repo.GetUserIdByAspNetUsrId((Guid)CurrentUser.ProviderUserKey);
				article.title = formData["title"];
				article.dateCreated = DateTime.Now;
				article.contentText = formData["contentText"];
				article.introText = formData["introText"];
				article.contentText.Replace("&lt;", "<").Replace("&gt;", ">").Replace("&amp;", "&");
				article.introText.Replace("&lt;", "<").Replace("&gt;", ">").Replace("&amp;", "&");
				article.isActive = formData.GetValues("isActive").Contains("true");
		
				//flokkur
				int selectedCatId = int.Parse(formData["Cats"]);

				//höfundar
				if (formData.GetValues("AuthorList").Count() > 0)
				{
					var addedItems = formData["AuthorList"].Split(',');
					for (int i = 0; i < addedItems.Length; i++)
						article.ArticleContentUserAuthors.Add(new ArticleContentUserAuthor { authorId = int.Parse(addedItems[i]) });
				}
				//skráð í db
				m_repo.AddArticle(article);
				article.ArticleToCategories.Add(new ArticleToCategory { articleId = article.id, categoryId = selectedCatId });
				m_repo.SaveChanges();
				return RedirectToAction("Index");
			}
			IEnumerable<SelectListItem> catList = m_repo.GetContentCategoryByParentId(2, 2);
			ViewData["Cats"] = catList;
			return View(article);
		}
        
        
        [Authorize(Roles= "Administrators")]
		public ActionResult Edit(int? id)
		{
			if (!id.HasValue)
			{
				return View("Index");
			}
			
			var article = m_repo.GetArticleById(id.Value);
			article.contentText = Server.HtmlDecode(article.contentText);
			article.introText = Server.HtmlDecode(article.introText);

			int selectedCatId = m_repo.GetArticleSelectedCategoryId(article.id);
			ViewData["oldCatId"] = selectedCatId.ToString();
			string strDropDownOptions = "";
			string strSelAttr = "";
            List<CategoryListItem> catList = new List<CategoryListItem>();
            catList = ToCatList(m_repo.GetAllCategories(), 1, "");
			foreach (var cl in catList)
			{
				strSelAttr = (selectedCatId == cl.valueText) ? " selected=\"selected\"" : "";
				strDropDownOptions += "<option value=\"" + cl.valueText.ToString() + "\" " + strSelAttr + ">" + cl.text + "</option>\n";
			}
			ViewData["Cats"] = strDropDownOptions;


			return View(article);
			
		}

		[HttpPost]
		[Authorize(Roles = "Administrators")]
		public ActionResult Edit(FormCollection formData)
		{
			ArticleContent article = new ArticleContent();
			long longId;
			if (long.TryParse(formData["articleId"], out longId))
				article.id = longId;

			if (!String.IsNullOrEmpty(formData["title"]))
			{
				System.Web.Security.MembershipUser CurrentUser = System.Web.Security.Membership.GetUser(User.Identity.Name);
				article.lastEditedByUserId = m_repo.GetUserIdByAspNetUsrId((Guid)CurrentUser.ProviderUserKey);
				article.title = formData["title"];
				article.isActive = formData.GetValues("isActive").Contains("true");
				article.contentText = formData["contentText"];
				article.contentText.Replace("&lt;", "<").Replace("&gt;", ">").Replace("&amp;", "&");
				article.introText = formData["introText"];
				article.introText.Replace("&lt;", "<").Replace("&gt;", ">").Replace("&amp;", "&");
				m_repo.UpdateArticle(article);
				m_repo.SaveChanges();

				int oldCatId;
				int.TryParse(formData["oldCategoryId"], out oldCatId);
				int currentCatId;
				int.TryParse(formData["Cats"], out currentCatId);

				m_repo.UpdateArticleToCategories(article.id, currentCatId, oldCatId);
				m_repo.SaveChanges();

				return RedirectToAction("Index");
			}
			return View(article);
		}

        [Authorize(Roles= "Administrators")]
        public ActionResult Delete(int id)
        {
            return View();
        }

        [HttpPost]
        [Authorize(Roles= "Administrators")]
        public ActionResult Delete(int id, FormCollection collection)
        {
            try
            {
                // TODO: Add delete logic here
 
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

		[Authorize]
		public ActionResult ArticleComments(long? id)
		{
			if (id.HasValue)
			{
				IEnumerable<ArticleComment> ac = m_repo.GetArticleCommentsByArticleId(id.Value);
				return View(ac);
			}

			return View("Index");
		}

        [HttpPost]
        public ActionResult Details(ArticleComment c, FormCollection coll)
        {
            c.articleId = long.Parse(coll["articleId"]);
            c.dateCommented = DateTime.Now;
            System.Web.Security.MembershipUser CurrentUser = System.Web.Security.Membership.GetUser(User.Identity.Name);
            c.commentedBy = m_repo.GetUserIdByAspNetUsrId((Guid)CurrentUser.ProviderUserKey);
            m_repo.ArticleComment(c);
            
            
            return RedirectToAction("Details",c.articleId);
        }

        #region HelperFunctions
        public List<CategoryListItem> ToCatList(IEnumerable<TextContentCategory> ltcc, int parentId, string indent)
        {
            List<CategoryListItem> returnable = new List<CategoryListItem>();
            IEnumerable<TextContentCategory> model = ltcc.Where(p => p.parentId == parentId);
            foreach (var item in model)
            {
                CategoryListItem into = new CategoryListItem();
                into.text = indent + item.categoryTitle;
                into.valueText = item.id;
                returnable.Add(into);
                returnable.AddRange(ToCatList(ltcc, item.id, indent + "---"));
            }
            return returnable;

        }

        #endregion

        #region WebServiceFunctions

        [HttpGet]
		[Authorize(Roles= "Administrators")]
		public ActionResult WSRemoveAuthor(long? articleId, long? userId)
		{
			if (articleId.HasValue && userId.HasValue)
			{
				m_repo.RemoveAuthorFromArticle(articleId.Value, userId.Value);
				m_repo.SaveChanges();
				return Json("true", JsonRequestBehavior.AllowGet);
			}
			return Json("false");		
		}

		[HttpGet]
		[Authorize(Roles = "Administrators")]
		public ActionResult WSGetAuthors(int? articleId)
		{
				var jsonData = (from usr in m_repo.GetUserAuthorsByArticleId(articleId.Value)
								select new { usrId = usr.id, usrFirstName = usr.firstName, usrLastName = usr.lastName });
				return Json(jsonData, JsonRequestBehavior.AllowGet);
		}

		[HttpGet]
		[Authorize(Roles = "Administrators")]
		public ActionResult WSGetExceptUsers(int? articleId)
		{
			List<JsonUser> allUsersWithNames = (from u in m_repo.GetAllUsersWithNames()
							select new JsonUser { id = u.id, firstName = u.firstName, lastName = u.lastName }).ToList( );

			List<JsonUser> userAuthors = (from usr in m_repo.GetUserAuthorsByArticleId(articleId.Value)
							select new JsonUser { id = usr.id, firstName = usr.firstName, lastName = usr.lastName }).ToList( );

			var usrList = allUsersWithNames.Except(userAuthors);

			var jsonData = (from exceptUsers in usrList
									select new 
									{ 
										Value = exceptUsers.id.ToString(), 
										Text = exceptUsers.firstName + " " + exceptUsers.lastName 
									}); 
			return Json(jsonData, JsonRequestBehavior.AllowGet);
		}

		[HttpGet]
		[Authorize(Roles = "Administrators")]
		public ActionResult WSAddAuthors(long? articleId, long? userId)
		{
			if (articleId.HasValue && userId.HasValue)
			{
				ArticleContent article = m_repo.GetArticleById(articleId.Value);
				article.ArticleContentUserAuthors.Add(new ArticleContentUserAuthor { authorId = userId.Value });
				m_repo.SaveChanges();
				return Json("true", JsonRequestBehavior.AllowGet);
			}
			return Json("false");
		}

		[HttpGet]
		public ActionResult WSArticleSearch(string strSearch)
		{
			var articles = m_repo.GetAllArticlesBySearchString(strSearch);
			var jsonData = (from a in m_repo.GetAllArticlesBySearchString(strSearch)
							select new
							{
								id = a.id.ToString(),
								title = a.title,
								introText = Server.HtmlDecode(a.introText)
							});
			return Json(jsonData, JsonRequestBehavior.AllowGet);
		}
	
		#endregion
	}
}
